package com.xiongkw.utils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.SimpleTimeZone;

/**
 * <ul>
 * <li>java时间工具类</li>
 * </ul>
 */
public class DateUtil {

    public static final String minutePattern = "yyyy-MM-dd HH:mm";
    public static final String datePattern = "yyyy-MM-dd";



    public static boolean isValidMinutePattern(String dateStr) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(minutePattern);
        try {
            simpleDateFormat.parse(dateStr);
        } catch (ParseException e) {
            return false;
        }
        return true;
    }

    public static Date parseMinutePatternDate(String dateStr) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(minutePattern);
        return simpleDateFormat.parse(dateStr);
    }

    public static String formatMinutePatternDate(Date date) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(minutePattern);
        return simpleDateFormat.format(date);
    }

    public static String formatDate(Date date) {
        return new SimpleDateFormat(datePattern).format(date);
    }

    public static String formatDate(Date date, String pattern) {
        return new SimpleDateFormat(pattern).format(date);
    }

    public static String formatDateWithTimeZooe(Date date, String pattern){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        simpleDateFormat.setCalendar(new GregorianCalendar(new SimpleTimeZone(0, "GMT")));
        return simpleDateFormat.format(date);
    }

    public static boolean isOverlap(Date leftFrom, Date leftTo, Date rightFrom, Date rightTo) {
        long leftFromTime = leftFrom.getTime();
        long leftToTime = leftTo.getTime();

        long rightFromTime = rightFrom.getTime();
        long rightToTime = rightTo.getTime();

        if (leftFromTime > leftToTime || rightFromTime > rightToTime) {
            throw new RuntimeException("the from time should be before the to time");
        }

        if (leftToTime < rightFromTime) {
            return false;
        }

        return leftFromTime <= rightToTime;
    }

    /**
     * 当前时间是否在{@code date}之后
     *
     * @param date 时间
     * @return 当前时间是否在{@code date}之前
     */
    public static boolean isAfter(Date date) {
        return new Date().after(date);
    }

    public static Date startOfDay(Date date) {
        if (date == null) {
            return null;
        }
        ZonedDateTime zonedDateTime = date.toInstant().atZone(ZoneId.systemDefault());
        LocalDateTime localDateTime = zonedDateTime.toLocalDate().atStartOfDay();
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    public static Date endOfDay(Date date) {
        if (date == null) {
            return null;
        }
        ZonedDateTime zonedDateTime = date.toInstant().atZone(ZoneId.systemDefault());
        LocalDateTime localDateTime = zonedDateTime.toLocalDate().atTime(LocalTime.MAX);
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    public static Date addDays(Date date, int days) {
        if (null == date) {
            return null;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(date); // 设置当前日期
        c.add(Calendar.DATE, days); // 日期加days天
        return c.getTime();
    }

    public static Date addMonth(Date date, int month) {
        if (null == date) {
            return null;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(date); // 设置当前日期
        c.add(Calendar.MONTH, month); // 日期加月份
        return c.getTime();
    }

    //月初
    public static Date startOfMonth(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date); // 设置当前日期
        c.set(Calendar.DAY_OF_MONTH, 1);
        return c.getTime();
    }

    //月末
    public static Date endOfMonth(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date); // 设置当前日期
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        return c.getTime();
    }

    // 下月初
    public static Date nextStartOfMonth(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date); // 设置当前日期
        c.add(Calendar.MONTH, 1);
        c.set(Calendar.DAY_OF_MONTH, c.getActualMinimum(Calendar.DAY_OF_MONTH));
        return c.getTime();
    }

    /**
     * 设置为当月的几号
     *
     * @param date
     * @param day
     * @return
     */
    public static Date setDay(Date date, int day) {
        Calendar c = Calendar.getInstance();
        c.setTime(date); // 设置当前日期
        c.set(Calendar.DAY_OF_MONTH, day);
        return c.getTime();
    }


    public static Date parseDate(String dateStr, String patten) {
        if (dateStr == null || patten == null) {
            return null;
        }
        DateFormat df = new SimpleDateFormat(patten);
        try {
            return df.parse(dateStr);
        } catch (ParseException e) {
            return null;
        }
    }

    public static int daysBetween(Date smdate,Date bdate) throws ParseException
    {
        SimpleDateFormat sdf=new SimpleDateFormat(datePattern);
        smdate=sdf.parse(formatDate(smdate));
        bdate=sdf.parse(sdf.format(bdate));
        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis();
        long between_days=(time2-time1)/(1000*3600*24);
        return Integer.parseInt(String.valueOf(between_days));
    }

}
